AuthenticateAsClient() is used by client components to perform authentication after connecting to a server. For our Tcp component, this must be called directly, while for our application-layer protocol components, it will be called automatically after the connection is established when SSL is enabled.
When AuthenticateAsClient() is called (either directly, or through top-level methods that will utilize it), two things may occur:
This will raise the RemoteCertificateValidationCallback specified by Tcp.Session.Security.ValidationCallback. This callback must be in the format:
C# |
Copy Code |
---|---|
using System.Net.Security; using System.Security.Cryptography.X509Certificates; bool RemoteCertificateValidation( Object sender, X509Certificate remoteCertificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { ... } |
Visual Basic |
Copy Code |
---|---|
Imports System.Net.Security Imports System.Security.Cryptography.X509Certificates Function RemoteCertificateValidation( _ ByVal sender As Object, _ ByVal remoteCertificate As X509Certificate, _ ByVal chain As X509Chain, _ ByVal sslPolicyErrors As SslPolicyErrors) As Boolean ... End Function |
Return true to accept the certificate, and false to refuse it. A value other than SslPolicyErrors.None for sslPolicyErrors indicates an issue with the certificate that the server presented. A flag of SslPolicyErrors.RemoteCertificateChainErrors indicates that chain.ChainStatus should be checked; enumerate through chain.ChainStatus, and check the value of chain.ChainStatus[index].Status for additional details.
During authentication, the remote certificate's common name (CN) (usually the server's fully qualified domain name) is compared to the value of ClientSecurity.TargetHost. If the values do not match, sslPolicyErrors will contain the SslPolicyErrors.RemoteCertificateNameMismatch flag. When ClientSecurity.TargetHost is left empty, Tcp.Session.RemoteEndPoint.HostNameOrAddress will be used instead.
AuthenticateAsClient() first checks if Tcp.Session.Security.SelectionCallback is null. If it is not null, that LocalCertificateSelectionCallback will be raised. This callback must be in the format:
C# |
Copy Code |
---|---|
using System.Security.Cryptography.X509Certificates; X509Certificate LocalCertificateSelection( Object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers) { ... } |
Visual Basic |
Copy Code |
---|---|
Imports System.Security.Cryptography.X509Certificates Function LocalCertificateSelection( _ ByVal sender As Object, _ ByVal targetHost As String, _ ByVal localCertificates As X509CertificateCollection, _ ByVal remoteCertificate As X509Certificate, _ ByVal acceptableIssuers() As String) As X509Certificate ... End Function |
Return a certificate within the callback, and that certificate will be used for authentication. Certificates may be accessed from the certificate store with the System.Security.Cryptography.X509Certificates.X509Store class:
C# |
Copy Code |
---|---|
using System.Security.Cryptography.X509Certificates; //The X509Store constructor overloads may be used to access different certificate stores X509Store certificateStore = new X509Store(); certificateStore.Open(OpenFlags.ReadOnly); X509Certificate2 cert = certificateStore.Certificates[0]; |
Visual Basic |
Copy Code |
---|---|
Imports System.Security.Cryptography.X509Certificates 'The X509Store constructor overloads may be used to access different certificate stores Dim certificateStore As New X509Store() certificateStore.Open(OpenFlags.ReadOnly) Dim cert As X509Certificate2 = certificateStore.Certificates(0) |
For a demonstration of selecting a certificate from the certificate store interactively, please see the CertificateListForm included with our samples.
If Tcp.Session.Security.SelectionCallback is null, AuthenticateAsClient() will examine Tcp.Session.Security.Certificates for a valid certificate; the first certificate in the collection that passes Microsoft's validation checks will be used for authentication.
For our server component, Tcp.AuthenticateAsServer(ServerSecurity) may be called after the client connects. ServerSecurity.ValidationCallback is identical to the client ValidationCallback, and will be raised when the client presents a certificate.
Set the ServerSecurity.Certificate property to specify the certificate to use for authentication.
The security protocol used will be automatically negotiated; to specify the protocols available for negotiation, Security.Protocols may be set to any combination of the SslProtocols enumeration.
Explicit security means that the initial connection to the server is not encrypted. After connecting, a command such as STARTTLS or STLS is sent by the client to the server per the protocol, and a secure connection is negotiated. Because explicit security is initiated after the STARTTLS command is sent, servers are able to accept explicit connections on the same port that accepts non-secure connections.
Implicit security means that the client and server will negotiate a secure connection when the connection is established. Because of this, a port is typically dedicated for implicit connections.
Explicit/Implicit implementation is protocol-specific; application-layer protocols such as Ftp, Imap, Smtp and Pop implement it, while upper-layer protocols such as Tcp and Udp do not. The method of encryption may be configured on our components with a property on Session.Security. The property's name may vary between components, but will always start with 'Encrypt'; for Ftp, this property is Session.Security.EncryptControl, and for our Email components, Session.Security.Encrypt.